﻿package com.vinyl.app
{
	import com.vinyl.command.*;
	import com.vinyl.app.*;
	import fl.transitions.easing.*;

	public class Timeline implements ICommand
	{
		private var _f: Function;
		private var _frame: Number;
		private var _frames: Array;
		
		public var activity:Activity;
		public var ease:Function;
		
		public var t:Number = 0; //프레임타임
		public var b:Number = 0; //시작
		public var c:Number = 1; //끝
		public var d:Number = 24; //두레이션
		public var value:Number  = 0;
		
		public function get currentframe(): Number
		{
			return _frame;
		}
		
		public function get totalframes(): Number
		{
			return _frames.length;
		}
		
		public function Timeline( $activity, $length )
		{
			activity = $activity;
			_frames = new Array( $length );
			_frame  = 0;
			_f = nextFrame;
			d = length;
			
			ease = Strong.easeIn;
		}
		
		public function play(): void
		{
			_f = nextFrame;
			activity.addTimelineListener( this );
		}
		
		public function gotoAndPlay( $frame: Number ): void
		{
			_frame = $frame;
			_frames[ $frame ].execute();
			_f = nextFrame;
			
			activity.addTimelineListener( this );
		}
		
		public function stop(): void
		{
			activity.removeTimelineListener( this );
		}
		
		function gotoAndStop( $frame: Number ): void
		{
			_frame = $frame;
			activity.removeTimelineListener( this );
			_frames[ $frame ].execute();
		}
		
		public function reverse(): void
		{
			_f = prevFrame;
			activity.addTimelineListener( this );
		}
		
		function gotoAndReverse( $frame: Number ): void
		{
			_frame = $frame;
			_frames[ $frame ].execute();
			_f = prevFrame;
			activity.addTimelineListener( this );
		}
		
		public function nextFrame(): void
		{
			if ( ++_frame == _frames.length ) _frame = 0; 
			value = Math.round ( ease( _frame, b, c, d ) );
			if ( _frames[ _frame ] ) _frames[ _frame ].execute();
		}
		
		public function prevFrame(): void
		{
			if( _frame-- < 1 ) _frame = _frames.length - 1;
			if( _frames[ _frame ] ) _frames[ _frame ].execute();
		}
		
		public function insertAt( $range: Array, $exe: ICommand ): void
		{
			var r: Number = $range.length;
			var s;
			
			while( --r > -1 )
			{
				s = $range[r];
				
				if( s is Array )
				{
					for( var i = s[0] ; i <= s[1] ; i++ )
					{
						_frames[i] = $exe;
					}
				}
				else
				{
					_frames[s] = $exe;
				}
			}
			
			for( i = 0 ; i < _frames.length ; i++ )
			{
				if( _frames[ i ] == undefined ) _frames[i] = Call.create( this, function func() { trace( "function : " + arguments ) }, "empty frame", i );
			}
		}
		
		public function removeAt( $range: Array, $exe: ICommand ): void
		{
			var r: Number = $range.length;
			var s;
			
			while( --r > -1 )
			{
				s = $range[r];
				
				if( s is Array )
				{
					for( var i = s[0] ; i <= s[1] ; i++ )
					{
						_frames[i] = Call.create( this, function func() { trace( "function : " + arguments ) }, "empty frame", i );
					}
				}
				else
				{
					_frames[s] = Call.create( this, function func() { trace( "function : " + arguments ) }, "empty frame", s );
				}
			}
			
			for( i = 0 ; i < _frames.length ; i++ )
			{
				if( _frames[ i ] == undefined ) _frames[i] = Call.create( this, function func() { trace( "function : " + arguments ) }, "empty frame", i );
			}
			
		}
		
		public function execute( ... args ):Function
		{
			return _f();
		}
	}
}



